package com.tenement.utils.ftpfileutil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;

public class FtpUtil {

	private static final Log logger = LogFactory.getLog(FtpUtil.class);

	FtpServerVo ftpServer = new FtpServerVo();

	FTPClient ftp = null;

	/*--------------------------------------连接FTP服务器开始-------------------------------------*/
	/**
	 * 配置FTP连接参数
	 * 
	 * @return
	 * @throws Exception
	 */
	public static FTPClientConfig getFTPClientConfig() throws Exception {

		logger.info("【-配置FTP连接参数-】");
		String systemKey = FTPClientConfig.SYST_UNIX;
		String serverLanguageCode = "zh";
		FTPClientConfig conf = new FTPClientConfig(systemKey);
		conf.setServerLanguageCode(serverLanguageCode);
		conf.setDefaultDateFormatStr("yyyy-MM-dd");
		return conf;

	}

	/**
	 * 连接FTP服务器
	 * 
	 * @param server
	 * @param port
	 * @param uname
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public FTPClient connectFTPServer(String server, int port, String userName, String password) throws Exception {

		// 初始化服务器信息
		ftpServer.setServer(server);
		ftpServer.setPort(port);
		ftpServer.setUserName(userName);
		ftpServer.setPassword(password);

		ftp = new FTPClient();

		try {

			ftp.setControlEncoding("UTF-8");
			ftp.configure(getFTPClientConfig());
			ftp.connect(ftpServer.getServer(), ftpServer.getPort());
			ftp.login(ftpServer.getUserName(), ftpServer.getPassword());

			// 设置被动模式,加上这句报异常：java.net.SocketException: Software caused
			// connection abort: recv failed
			// ftp.enterLocalPassiveMode();

			ftp.setConnectTimeout(2000);

			/*
			 * 响应信息确定答复代码是否为正面完成答复。 所有以2开头的代码都是正面完成答案。
			 * FTP服务器将在最终成功完成一个命令时发送一个肯定的完成响应。 返回值解释： 200Command okay
			 * 230用户登录，继续。 如果适用，退出。 User logged in, proceed. Logged out if
			 * appropriate.
			 */
			int replyCode = ftp.getReplyCode();

			if ((!FTPReply.isPositiveCompletion(replyCode))) {
				// 关闭Ftp连接
				// closeFTPClient();
				ftp.disconnect();
				// 释放空间
				ftp = null;
				throw new Exception("登录FTP服务器失败,请检查![Server:" + ftpServer.getServer() + "、" + "User:"
						+ ftpServer.getUserName() + "、" + "Password:" + ftpServer.getPassword());
			} else {
				logger.info("【-连接成功-replyCode】" + replyCode);
				// 文件类型,默认是ASCII
				ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
				return ftp;
			}
		} catch (Exception e) {
			ftp.disconnect();
			ftp = null;
			throw e;
		}
	}

	/**
	 * 关闭FTP连接
	 * 
	 * @param ftp
	 * @throws Exception
	 */
	public static void closeFTPClient(FTPClient ftp) throws Exception {

		try {
			if (ftp.isConnected())
				ftp.disconnect();
		} catch (Exception e) {
			throw new Exception("关闭FTP服务出错!");
		}
	}

	/**
	 * 关闭FTP连接
	 * 
	 * @throws Exception
	 */
	public void closeFTPClient() throws Exception {

		closeFTPClient(ftp);

	}
	/*--------------------------------------连接FTP服务器结束-------------------------------------*/

	/*----------------------------------------工具方法开始----------------------------------------*/
	/**
	 * 改变工作目录，如失败则创建文件夹
	 * 
	 * @param remoteFoldPath
	 */
	public void changeDirectory(String remoteFoldPath) throws Exception {

		if (remoteFoldPath != null) {
			boolean flag = ftp.changeWorkingDirectory(remoteFoldPath);
			if (!flag) {
				ftp.makeDirectory(remoteFoldPath);
				ftp.changeWorkingDirectory(remoteFoldPath);
			}
		}

	}

	/**
	 * 检查文件是否存在
	 * 
	 * @param filePath
	 * @return
	 * @throws Exception
	 */
	public boolean checkFileExist(String filePath) throws Exception {
		boolean flag = false;
		File file = new File(filePath);
		if (!file.exists()) {
			throw new Exception("文件不存在,请检查!");
		} else {
			flag = true;
		}
		return flag;
	}

	/**
	 * 获取文件名,不包括后缀
	 * 
	 * @param filePath
	 * @return
	 */
	public String getFileNamePrefix(String filePath) throws Exception {

		boolean flag = this.checkFileExist(filePath);
		if (flag) {
			File file = new File(filePath);
			String fileName = file.getName();
			String _fileName = fileName.substring(0, fileName.lastIndexOf("."));
			return _fileName;
		}
		return null;
	}
	/*----------------------------------------工具方法开始----------------------------------------*/

	/*-------------------------------文件类File上传到FTP服务器开始-------------------------------------*/

	/**
	 * 上传文件到FTP根目录
	 * 
	 * @param localFile
	 * @param newName
	 * @throws Exception
	 */
	public void uploadFile(String localFile, String newName) throws Exception {
		InputStream input = null;
		try {
			File file = null;
			if (checkFileExist(localFile)) {
				file = new File(localFile);
			}
			input = new FileInputStream(file);
			boolean result = ftp.storeFile(newName, input);
			logger.info("【-File类上传到FTP根目录成功？-】" + result);
			if (!result) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
	}

	/**
	 * 上传文件到指定的FTP路径下
	 * 
	 * @param localFile
	 * @param newName
	 * @param remoteFoldPath
	 * @throws Exception
	 */
	public void uploadFile(String localFile, String newName, String remoteFoldPath) throws Exception {
		InputStream input = null;
		try {
			File file = null;
			if (checkFileExist(localFile)) {
				file = new File(localFile);
			}
			input = new FileInputStream(file);

			// 改变当前路径到指定路径
			this.changeDirectory(remoteFoldPath);
			boolean result = ftp.storeFile(newName, input);
			logger.info("【-File类上传到FTP指定目录成功？-】" + result);
			if (!result) {
				throw new Exception("文件上传失败!");
			}

		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
	}
	/*-------------------------------文件类File上传到FTP服务器结束-------------------------------------*/

	/*--------------------InputStream字节输入流上传到FTP服务器开始-------------------------------------*/
	/**
	 * 上传文件到FTP根目录
	 * 
	 * @param input
	 * @param newName
	 * @throws Exception
	 */
	public void uploadFile(InputStream input, String newName) throws Exception {
		try {
			boolean result = ftp.storeFile(newName, input);
			logger.info("【-InputStream类上传到FTP根目录成功？-】" + result);
			if (!result) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}

	}

	/**
	 * 上传文件到指定的FTP路径下
	 * 
	 * @param input
	 * @param newName
	 * @param remoteFoldPath
	 * @throws Exception
	 */
	public void uploadFile(InputStream input, String newName, String remoteFoldPath) throws Exception {
		try {
			// 改变当前路径到指定路径
			this.changeDirectory(remoteFoldPath);
			boolean result = ftp.storeFile(newName, input);
			logger.info("【-InputStream类上传到FTP指定目录成功？-】" + result);
			if (!result) {
				throw new Exception("文件上传失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (input != null) {
				input.close();
			}
		}
	}

	/*--------------------InputStream字节输入流上传到FTP服务器结束-------------------------------------*/

	/*-------------------------------File从FTP指定的路径下载文件开始-------------------------------------*/
	/**
	 * 从FTP指定的路径下载文件
	 * 
	 * @param remotePath
	 * @param localPath
	 */
	public void downloadFile(String remotePath, String localPath) throws Exception {

		OutputStream output = null;
		try {
			File file = null;
			if (checkFileExist(localPath)) {
				file = new File(localPath);
			}
			output = new FileOutputStream(file);
			boolean result = ftp.retrieveFile(remotePath, output);
			logger.info("【-File类从FTP指定的路径下载文件成功？-】" + result);
			if (!result) {
				throw new Exception("文件下载失败!");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if (output != null) {
				output.close();
			}
		}

	}
	
	/*-------------------------------File从FTP指定的路径下载文件结束-------------------------------------*/

	/*-------------------------------File从FTP指定的路径下载文件开始-------------------------------------*/
	/*-------------------------------File从FTP指定的路径下载文件结束-------------------------------------*/

}
